home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-01-11 | 10.5 KB | 378 lines | [TEXT/CWIE] |
- // TNetworkSession.cp - Macintosh OpenTransport Network Server class object
- //
- // Apple Macintosh Developer Technical Support
- // Written by: Vinne Moscaritolo
- //
- // Copyright (work in progress) Apple Computer, Inc All rights reserved.
- //
- // You may incorporate this sample code into your applications without
- // restriction, though the sample code has been provided "AS IS" and the
- // responsibility for its operation is 100% yours. However, what you are
- // not permitted to do is to redistribute the source as "DSC Sample Code"
- // after having made changes. If you're going to re-distribute the source,
- // we require that you make it clear in the source that the code was
- // descended from Apple Sample Code, but that you've made changes.
- //
-
- #include "TNetworkSession.h"
- #include "TNetworkAcceptor.h"
-
-
- // ---------------------------------------------------------------------------
- // NotifyProc (queue up an event)
- // ---------------------------------------------------------------------------
- // TNetworkSession OT Notifier Proc
-
- pascal void TNetworkSession::NotifyProc( TNetworkSession* theSession, OTEventCode theEvent, OTResult theResult, void* theParam)
- {
- try
- {
- //// No-copy memory was released
- if(theEvent == T_MEMORYRELEASED) TNetworkBuf::Release(theParam);
-
- // Data avail at endpoint
- else if (theEvent == T_DATA) theSession->EventDataAvail();
-
- // queue all others
- else QUEUE_NET_EVENT( theSession, theEvent, theResult, theParam);
- }
-
- catch (TNetworkException &ex)
- {
- DebugStr("\p TNetworkSession::NotifyProc -- Network Exception.. ");
- }
-
- catch(TMacException &ex)
- {
- DebugStr("\p TNetworkSession::NotifyProc -- Mac Exception.. ");
- }
-
- catch(...) // catch everything
- {
- DebugStr("\p TNetworkSession::NotifyProc -- Other Exception.. ");
- }
-
- }
-
-
- // ---------------------------------------------------------------------------
- // TNetworkSession
- // ---------------------------------------------------------------------------
- // Default Constructor
-
- TNetworkSession::TNetworkSession(TNetworkAcceptor* theServer)
- {
- TNetworkEndpointDescriptor* theEPD;
-
- // Setup a new endpoint
- fEndPoint = kOTInvalidEndpointRef;
- fData = nil;
- fServer = theServer;
-
- theEPD = theServer->GetEPD();
-
- ThrowIfOTErr( ::OTAsyncOpenEndpoint(theEPD->GetConfiguration() ,0,&fInfo, NotifyProc, this ) );
-
- }
-
- // ---------------------------------------------------------------------------
- // ~TNetworkListener
- // ---------------------------------------------------------------------------
- // Destructor
-
- TNetworkSession::~TNetworkSession()
- {
- // close up enpoint
- if(fEndPoint != kOTInvalidEndpointRef) ::OTCloseProvider(fEndPoint);
- if( fData) delete fData;
- };
-
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::Done( )
- // ---------------------------------------------------------------------------
- // Session Thread completed..
-
- void TNetworkSession::Done()
- {
- OTResult state = ::OTGetEndpointState(fEndPoint);
-
- // If your not shutdown yet
- if(state == T_DATAXFER) {
-
- // flush out all waiting data
- fioStream << flush;
-
- // and disconnect the endpoint
- if( (fInfo.flags == T_COTS_ORD) || (fInfo.flags == T_TRANS_ORD))
- ::OTSndOrderlyDisconnect(fEndPoint);
- else
- ::OTSndDisconnect (fEndPoint,&fCallInfo);
- }
-
- }
-
-
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::HandleEvent (TNetworkEvent*)
- // ---------------------------------------------------------------------------
- // Network Server Event Handler
-
- void TNetworkSession::HandleEvent (TNetworkEvent* theEvent)
- {
- switch ( theEvent->fEvent ){
-
- ///// OpenEndpoint Completed
- case T_OPENCOMPLETE:
- EventOpenComplete(theEvent);
- break;
- ///// Endpoint accepted connection
- case T_PASSCON:
- EventPassCon(theEvent);
- break;
- ///// Client Quit
- case T_DISCONNECT:
- EventDisconnect(theEvent);
- break;
- ///// remote client request release
- case T_ORDREL:
- EventOrdRelease(theEvent);
- break;
- ///// Connection Torn Down
- case T_DISCONNECTCOMPLETE:
- EventDisconnectComplete(theEvent);
- break;
- ///// Winding down
- case T_UNBINDCOMPLETE:
- EventUnbindComplete(theEvent);
- break;
- //// Data Available
- case T_DATA:
- EventDataAvail(theEvent);
- break;
- //// Expidited Data Available
- case T_EXDATA:
- EventExDataAvail(theEvent);
- break;
- //// No-copy memory was released // DEBUG ONLY...
- case T_MEMORYRELEASED:
- EventMemoryReleased(theEvent);
- break;
- ////..Other ...
- default:
- EventOther(theEvent);
- break;
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::EventOpenComplete(theEvent )
- // ---------------------------------------------------------------------------
- // Network Endpoint Open Completion Handler
-
- void TNetworkSession::EventOpenComplete(TNetworkEvent* theEvent)
- {
- // record endpoint
- fEndPoint = (EndpointRef) theEvent->fParam;
-
- // Setup Tcall/Tdisconnect area
- fCallInfo.addr.len = 0;
- fCallInfo.opt.len = 0;
- fCallInfo.udata.len = 0;
- fDisconInfo.udata.len = 0;
-
- fCallInfo.addr.maxlen = (fInfo.addr == T_INVALID)?0:fInfo.addr;
- fCallInfo.opt.maxlen = (fInfo.options == T_INVALID)?0:fInfo.options;
- fCallInfo.udata.maxlen = (fInfo.connect == T_INVALID)?0:fInfo.connect;
- fDisconInfo.udata.maxlen= (fInfo.discon == T_INVALID)?0:fInfo.discon;
-
- // Alloacte enough ram for Tcall & TDiscon buffers
- size_t buffSize = fCallInfo.addr.maxlen
- + fCallInfo.opt.maxlen
- + (fCallInfo.udata.maxlen > fDisconInfo.udata.maxlen
- ? fCallInfo.udata.maxlen
- : fDisconInfo.udata.maxlen);
-
- fData = new UInt8[buffSize];
-
- fCallInfo.addr.buf = &fData[0];
- fCallInfo.opt.buf = fCallInfo.addr.buf + fCallInfo.addr.maxlen;
- fCallInfo.udata.buf = fCallInfo.opt.buf + fCallInfo.opt.maxlen;
- fDisconInfo.udata.buf = fCallInfo.udata.buf; // Disconnect and connect share the same data area
-
- // Enable AckSends
- ThrowIfOTErr( ::OTAckSends(fEndPoint));
-
- // attach endpoint to stream;
- fioStream.attach(fEndPoint,&fInfo);
-
- // Inform Server that we are ready to be used
- QUEUE_NET_EVENT( fServer, TNetworkAcceptor::kSessionAvailable, noErr, this);
-
- }
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::EventPassCon(theEvent)
- // ---------------------------------------------------------------------------
- // Network Endpoint Handoff Completion Handler
-
- void TNetworkSession::EventPassCon(TNetworkEvent* theEvent)
- {
- try{
- Start(); // start thread.
- }
- catch(...){
- Done();
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventDisconnect
- // ---------------------------------------------------------------------------
- // Connecting client quit
-
- void TNetworkSession::EventDisconnect(TNetworkEvent* theEvent)
- {
- OSStatus ErrNo;
-
- if( ErrNo = ::OTRcvDisconnect(fEndPoint, &fDisconInfo))
- ErrNo = ErrNo ;
-
- if( ErrNo = ::OTUnbind(fEndPoint)) ;
- ErrNo = ErrNo ;
-
- }
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::EventOrdRelease
- // ---------------------------------------------------------------------------
- // remote client request release
-
- void TNetworkSession::EventOrdRelease(TNetworkEvent* theEvent)
- {
- OSStatus ErrNo;
-
- if( ErrNo = ::OTRcvOrderlyDisconnect(fEndPoint))
- ErrNo = ErrNo ;
-
- if( ErrNo = ::OTUnbind(fEndPoint)) ;
- ErrNo = ErrNo ;
-
- // shut down thread if still running
- Stop();
-
- }
-
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::EventDisconnectComplete
- // ---------------------------------------------------------------------------
- // Connection Torn Down
-
- void TNetworkSession::EventDisconnectComplete(TNetworkEvent* theEvent)
- {
- OSStatus ErrNo;
- if( ErrNo = ::OTUnbind(fEndPoint)) ;
- ErrNo = ErrNo ;
- }
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::EventUnbindComplete
- // ---------------------------------------------------------------------------
- // Network Endpoint Unbind Completion Handler
-
- void TNetworkSession::EventUnbindComplete(TNetworkEvent* theEvent)
- {
-
- // notify server that your done...
- QUEUE_NET_EVENT( fServer, TNetworkAcceptor::kSessionAvailable , noErr, this);
- }
-
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::EventDataAvail
- // ---------------------------------------------------------------------------
- // Data Available
-
-
- void TNetworkSession::EventDataAvail(TNetworkEvent* theEvent)
- {
- #pragma unused (theEvent)
- OTFlags flags;
- OTResult status;
- OTBuffer* buffP;
- OTBufferInfo buffInfo;
- size_t actCount;
- char* buffer;
-
- // do while data left in OT
- while((status = ::OTRcv(fEndPoint, &buffP, kOTNetbufDataIsOTBufferStar, &flags)) > 0) {
-
- // get count of bytes in buffer
- OTInitBufferInfo(&buffInfo, buffP);
-
- // loop until no longer hungry
- do{
- // reserve buffer space
- ThrowIfNil( buffer = fioStream.ReserveBuffer(status, &actCount));
-
- // read data into buffer
- ::OTReadBuffer(&buffInfo, buffer, &actCount);
- fioStream.EnqueueBuffer(buffer,actCount);
-
- status -= actCount;
-
- } while( status > 0 );
-
- // return OTBuffer to system
- ::OTReleaseBuffer(buffP);
- }
-
-
- // Did we read all the data
- if(status == kOTNoDataErr) return;
-
- // was the endpoint not ready yet
- else if(status == kOTStateChangeErr) QUEUE_NET_EVENT(this, T_DATA, 0, 0);
-
- // Check for Rcv Error
- else ThrowIfOTErr( status );
-
- };
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::EventExDataAvail
- // ---------------------------------------------------------------------------
- // Expidited Data Available
-
- void TNetworkSession::EventExDataAvail(TNetworkEvent* theEvent)
- {
- };
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::EventMemoryReleased(theEvent )
- // ---------------------------------------------------------------------------
- // Network Endpoint Memory released hander
-
- void TNetworkSession::EventMemoryReleased(TNetworkEvent* theEvent)
- {
- TNetworkBuf::Release((void*)theEvent->fParam );
- }
-
-
-
- // ---------------------------------------------------------------------------
- // TNetworkSession::EventOther
- // ---------------------------------------------------------------------------
- // Other random event
-
- void TNetworkSession::EventOther(TNetworkEvent* theEvent)
- {
- if(theEvent)
- ThrowIfOTErr(noErr);
- };
-
-